package org.eiahe.hr.performance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.ehe.common.core.exception.ServiceException;
import org.ehe.common.core.utils.SpringUtils;
import org.ehe.common.satoken.utils.LoginHelper;
import org.eiahe.hr.performance.domain.PerformanceIndicator;
import org.eiahe.hr.performance.domain.PerformancePositionIndicator;
import org.eiahe.hr.performance.domain.bo.PerformanceIndicatorBo;
import org.eiahe.hr.performance.mapper.PerformanceIndicatorMapper;
import org.eiahe.hr.performance.mapper.PerformancePositionIndicatorMapper;
import org.eiahe.hr.performance.service.IPerformanceIndicatorService;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Collection;

/**
 * 绩效指标Service业务层处理
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@Service
public class PerformanceIndicatorServiceImpl extends ServiceImpl<PerformanceIndicatorMapper, PerformanceIndicator>
        implements IPerformanceIndicatorService {

    private final PerformanceIndicatorMapper baseMapper;

    @Override
    public PerformanceIndicator queryById(Long indicatorId) {
        return baseMapper.selectById(indicatorId);
    }

    @Override
    public TableDataInfo<PerformanceIndicator> queryPageList(PerformanceIndicatorBo indicator, PageQuery pageQuery) {
        LambdaQueryWrapper<PerformanceIndicator> lqw = buildQueryWrapper(indicator);
        Page<PerformanceIndicator> page = baseMapper.selectPage(pageQuery.build(), lqw);
        return TableDataInfo.build(page);
    }

    private LambdaQueryWrapper<PerformanceIndicator> buildQueryWrapper(PerformanceIndicatorBo indicator) {
        LambdaQueryWrapper<PerformanceIndicator> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(indicator.getIndicatorName()), PerformanceIndicator::getIndicatorName,
                indicator.getIndicatorName());
        lqw.eq(StringUtils.isNotBlank(indicator.getCycleType()), PerformanceIndicator::getCycleType,
                indicator.getCycleType());
        lqw.eq(StringUtils.isNotBlank(indicator.getIndicatorType()), PerformanceIndicator::getIndicatorType,
                indicator.getIndicatorType());
        lqw.eq(StringUtils.isNotBlank(indicator.getStatus()), PerformanceIndicator::getStatus, indicator.getStatus());

        // 如果设置了parentId为0或null，只查询顶级指标
        if (indicator.getParentId() == null || indicator.getParentId() == 0L) {
            lqw.and(wrapper -> wrapper.isNull(PerformanceIndicator::getParentId));
        }
        // 如果设置了parentId且不为0，查询指定父级的子指标
        else if (indicator.getParentId() > 0L) {
            lqw.eq(PerformanceIndicator::getParentId, indicator.getParentId());
        }

        lqw.orderByAsc(PerformanceIndicator::getSortOrder);
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(PerformanceIndicator indicator) {
        // 验证父指标是否存在
        validateParentIndicator(indicator);

        // 验证名称是否重复
        validateNameDuplicate(indicator);

        // 验证权重
        validateWeight(indicator);

        // 设置默认值
        if (indicator.getLevel() == null) {
            indicator.setLevel(1);
        }
        if (indicator.getSortOrder() == null) {
            indicator.setSortOrder(0);
        }

        return baseMapper.insert(indicator) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(PerformanceIndicator indicator) {
        // 验证父指标是否存在
        validateParentIndicator(indicator);

        // 验证名称是否重复
        validateNameDuplicate(indicator);

        // 验证权重
        validateWeight(indicator);

        return baseMapper.updateById(indicator) > 0;
    }

    /**
     * 验证同一父类下名称是否重复
     *
     * @param indicator 绩效指标
     */
    private void validateNameDuplicate(PerformanceIndicator indicator) {
        if (StringUtils.isBlank(indicator.getIndicatorName())) {
            return;
        }

        LambdaQueryWrapper<PerformanceIndicator> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceIndicator::getIndicatorName, indicator.getIndicatorName());
        lqw.eq(PerformanceIndicator::getTenantId, LoginHelper.getTenantId());
        lqw.eq(PerformanceIndicator::getDelFlag, "0");

        // 如果设置了父指标ID，则在同一父指标下检查名称重复
        if (indicator.getParentId() != null) {
            lqw.eq(PerformanceIndicator::getParentId, indicator.getParentId());
        } else {
            // 如果没有父指标，则在顶级指标中检查名称重复
            lqw.isNull(PerformanceIndicator::getParentId);
        }

        // 如果是更新操作，排除自身
        if (indicator.getIndicatorId() != null) {
            lqw.ne(PerformanceIndicator::getIndicatorId, indicator.getIndicatorId());
        }

        PerformanceIndicator existing = baseMapper.selectOne(lqw);
        if (existing != null) {
            throw new ServiceException("在同一层级下已存在相同名称的指标：" + indicator.getIndicatorName());
        }
    }

    /**
     * 验证父指标是否存在
     *
     * @param indicator 绩效指标
     */
    private void validateParentIndicator(PerformanceIndicator indicator) {
        // 如果设置了父指标ID且不为0或null，则验证父指标是否存在
        if (indicator.getParentId() != null && indicator.getParentId() > 0) {
            PerformanceIndicator parent = baseMapper.selectById(indicator.getParentId());
            if (parent == null) {
                throw new ServiceException("父指标不存在，请先创建父指标");
            }

            // 验证层级不能超过3级
            if (parent.getLevel() != null && parent.getLevel() >= 2) {
                throw new ServiceException("指标层级不能超过2级");
            }

            // 设置当前指标的层级
            indicator.setLevel(parent.getLevel() + 1);
        } else {
            // 如果没有父指标，则为顶级指标
            indicator.setParentId(null); // 改为null而不是0，以避免外键约束问题
            indicator.setLevel(1);
        }
    }

    /**
     * 验证权重是否合法
     * 同一层级的指标权重之和不能超过100%
     *
     * @param indicator 绩效指标
     */
    private void validateWeight(PerformanceIndicator indicator) {
        // 如果没有设置权重，直接返回
        if (indicator.getWeight() == null) {
            return;
        }

        // 获取同层级同父节点的其他指标
        LambdaQueryWrapper<PerformanceIndicator> lqw = Wrappers.lambdaQuery();
        // 修复：正确处理parentId为null的情况
        if (indicator.getParentId() != null) {
            lqw.eq(PerformanceIndicator::getParentId, indicator.getParentId());
        } else {
            lqw.isNull(PerformanceIndicator::getParentId);
        }
        lqw.eq(PerformanceIndicator::getTenantId, indicator.getTenantId());
        lqw.eq(PerformanceIndicator::getDelFlag, "0");

        // 如果是更新操作，排除自身
        if (indicator.getIndicatorId() != null) {
            lqw.ne(PerformanceIndicator::getIndicatorId, indicator.getIndicatorId());
        }

        // 计算同层级指标权重总和
        BigDecimal totalWeight = baseMapper.selectList(lqw).stream()
                .map(PerformanceIndicator::getWeight)
                .filter(weight -> weight != null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 加上当前指标的权重
        BigDecimal currentWeight = indicator.getWeight() != null ? indicator.getWeight() : BigDecimal.ZERO;
        BigDecimal sumWeight = totalWeight.add(currentWeight);

        // 验证权重总和不能超过100%
        if (sumWeight.compareTo(new BigDecimal("100")) > 0) {
            throw new ServiceException("同层级指标权重之和不能超过100%，当前总权重为：" + sumWeight + "%");
        }
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // 校验：检查是否被岗位关联使用
            PerformancePositionIndicatorMapper piMapper = SpringUtils.getBean(PerformancePositionIndicatorMapper.class);
            LambdaQueryWrapper<PerformancePositionIndicator> piLqw = Wrappers.lambdaQuery();
            piLqw.in(PerformancePositionIndicator::getIndicatorId, ids);
            piLqw.eq(PerformancePositionIndicator::getDelFlag, "0");
            long count = piMapper.selectCount(piLqw);

            if (count > 0) {
                throw new ServiceException("该指标已被" + count + "个岗位使用，请先解除关联");
            }
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
